'use strict';

const Snowflake = require('../libs/snowflake');
const fs = require('fs-extra');
const path = require('path');

module.exports = {
    /**
     * 时间格式化处理
     * @param {*} now  时间
     * @param {*} mask 格式 例如"yyyy-MM-dd HH:mm"
     */
    getFormatDate(now, mask) {
        let d = now;
        let zeroize = function (value, length) {
            if (!length) length = 2;
            value = String(value);
            let zeros = '';
            for (let i = 0; i < (length - value.length); i++) {
                zeros += '0';
            }
            return zeros + value;
        };
        return mask.replace(/"[^"]*"|'[^']*'|\b(?:d{1,4}|m{1,4}|yy(?:yy)?|([hHMstT])\1?|[lLZ])\b/g, function ($0) {
            switch ($0) {
                case 'd':
                    return d.getDate();
                case 'dd':
                    return zeroize(d.getDate());
                case 'ddd':
                    return ['Sun', 'Mon', 'Tue', 'Wed', 'Thr', 'Fri', 'Sat'][d.getDay()];
                case 'dddd':
                    return ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday'][d.getDay()];
                case 'M':
                    return d.getMonth() + 1;
                case 'MM':
                    return zeroize(d.getMonth() + 1);
                case 'MMM':
                    return ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'][d.getMonth()];
                case 'MMMM':
                    return ['January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December'][d.getMonth()];
                case 'yy':
                    return String(d.getFullYear()).substr(2);
                case 'yyyy':
                    return d.getFullYear();
                case 'h':
                    return d.getHours() % 12 || 12;
                case 'hh':
                    return zeroize(d.getHours() % 12 || 12);
                case 'H':
                    return d.getHours();
                case 'HH':
                    return zeroize(d.getHours());
                case 'm':
                    return d.getMinutes();
                case 'mm':
                    return zeroize(d.getMinutes());
                case 's':
                    return d.getSeconds();
                case 'ss':
                    return zeroize(d.getSeconds());
                case 'l':
                    return zeroize(d.getMilliseconds(), 3);
                case 'L':
                    let m = d.getMilliseconds();
                    if (m > 99) m = Math.round(m / 10);
                    return zeroize(m);
                case 'tt':
                    return d.getHours() < 12 ? 'am' : 'pm';
                case 'TT':
                    return d.getHours() < 12 ? 'AM' : 'PM';
                case 'Z':
                    return d.toUTCString().match(/[A-Z]+$/);
                // Return quoted strings with the surrounding quotes removed
                default:
                    return $0.substr(1, $0.length - 2);
            }
        });
    },

    /**
     * 字符格式化处理 处理的格式为=> stringFormat("{0}"你好,"中国")
     * @return {*} 返回正常格式字符
     */
    stringFormat() {
        if (arguments.length == 0)
            return null;
        let str = arguments[0];
        for (let i = 1; i < arguments.length; i++) {
            let re = new RegExp('\\{' + (i - 1) + '\\}', 'gm');
            str = str.replace(re, arguments[i]);
        }
        return str;
    },

    /**
     * 实现VBScript的DateAdd功能
     * let now = new Date();
     * let newDate = dateAdd( "d", 5, now);
     * @param {*} interval 字符串表达式，表示要添加的时间间隔
     * @param {*} number 数值表达式，表示要添加的时间间隔的个数
     * @param {*} date 时间对象
     * @return {*} 新的时间对象
     */
    dateAdd(interval, number, date) {
        switch (interval) {
            case "y":
                date.setFullYear(date.getFullYear() + number);
                break;
            case "q":
                date.setMonth(date.getMonth() + number * 3);
                break;
            case "M":
                date.setMonth(date.getMonth() + number);
                break;
            case "w":
                date.setDate(date.getDate() + number * 7);
                break;
            case "d":
                date.setDate(date.getDate() + number);
                break;
            case "h":
                date.setHours(date.getHours() + number);
                break;
            case "m":
                date.setMinutes(date.getMinutes() + number);
                break;
            case "s":
                date.setSeconds(date.getSeconds() + number);
                break;
            default:
                date.setDate(date.getDate() + number);
                break;
        }
        return date;
    },

    /**
     * 手机号码验证
     * 移动号码段:134 135 136 137 138 139 147 148 150 151 152 157 158 159  165 172 178 182 183 184 187 188 198
     * 联通号码段:130 131 132 145 146 155 156 166 171 175 176 185 186
     * 电信号码段:133 149 153 173 174 177 180 181 189 199
     * 虚拟运营商:170
     * @param cellphone 待检测手机号码
     * @returns {boolean}
     */
    checkCellphone(cellphone) {
        let reg =
            /^(((13[0-9]{1})|(14[5-9]{1})|(15[0-3]{1})|(15[5-9]{1})|(16[5-6]{1})|(17[0-8]{1})|(18[0-9]{1})|(19[0-9]{1}))+\d{8})$/;
        let isOk = true;
        if (cellphone.trim().match(reg) == null)
            isOk = false;
        return isOk;
    },

    /**
     * 字符串转int
     * @param {*} string
     */
    parseInt(string) {
        if (typeof string === 'number') return string;
        if (!string) return string;
        return parseInt(string) || 0;
    },

    /**
     * 创建guid16位
     */
    getGuid16() {
        return 'xxxxxxxxxxxxxxxx'.replace(/[xy]/g, function (c) {
            let r = Math.random() * 16 | 0,
                v = c == 'x' ? r : (r & 0x3 | 0x8);
            return v.toString(16);
        });
        // let tempSnowflake = new Snowflake(1n, 1n, 0n);
        // let tempId = tempSnowflake.nextId();
        // return tempId.toString(16);
    },
    /**
     *  随机生成n个数字
     */
    getRandomNumber(n) {
        var arr = new Array(n); //用于存放随机数
        var randomNumber = ''; //存放随机数
        let i, j = 0;

        for (i = 0; i < arr.length; i++)
            arr[i] = parseInt(Math.random() * 10);
        var flag = 0;
        for (i = 0; i < arr.length - 1; i++) {
            for (j = i + 1; j < arr.length; j++) {
                if (arr[i] == arr[j]) {
                    flag = 1;
                    break;
                }
            }
            if (flag) break;
        }
        for (i = 0; i < arr.length; i++) {
            randomNumber += arr[i];
        }
        return randomNumber;
    },

    /**
     * 获取token
     * @param {*} ctx ctx对象
     */
    getAccessToken(ctx) {
        let bearerToken = ctx.get('authorization');
        return bearerToken && bearerToken.replace("Bearer ", "");
    },

    /**
     * 校验 Token
     * @param {*} ctx ctx对象
     * @param {*} userId  用户id
     */
    verifyToken(ctx, userId) {
        if(true){
            ctx.status = 200;
            return true;
        }
        let token = this.getAccessToken(ctx);
        let verifyResult = ctx.service.units.verifyToken(token);
        if (!verifyResult.verify) {
            ctx.status = 200;
            ctx.body = {
                code: -2,
                msg: this.ctx.__('tokenTimeout') 
            };
            return false;
        }
        if (userId != verifyResult.message.id) {
            ctx.status = 200;
            ctx.body = {
                code: 2,
                msg:this.ctx.__('siginError')
            };
            return false;
        }
        return true;
    },
    /**
       * 校验 Token
       * @param {*} ctx ctx对象
       * @param {*} userId  用户id
       */
    verifySocketToken(ctx,token, userId) {
       token = token && token.replace("Bearer ", "");
        let verifyResult = ctx.service.units.verifyToken(token);
        if (!verifyResult.verify) {
            ctx.status = 200;
            ctx.body = {
                code: -2,
                msg:  this.ctx.__('tokenTimeout')  
            };
            return false;
        }
        if (userId != verifyResult.message.id) {
            ctx.status = 200;
            ctx.body = {
                code: 2,
                msg: this.ctx.__('siginError')
            };
            return false;
        }
        return true;
    },
    /**
     * 列出文件夹下所有文件
     * @param {*} path 文件夹地址
     */
    listDir(path) {
        return new Promise((resolve, reject) => {
            fs.readdir(path, (err, data) => {
                if (err) {
                    reject(err)
                    return
                }
                // 把mac系统下的临时文件去掉
                if (data && data.length > 0 && data[0] === '.DS_Store') {
                    data.splice(0, 1)
                }
                resolve(data)
            })
        })
    },

    /**
     * 睡眠操作
     * @param {*} time 睡眠时长 单位毫秒
     */
    sleep(time) {
        return new Promise(resolve => setTimeout(resolve, time));
    },

    /**
     * 目录创建
     * @param {*} dirpath 要创建的目录,支持多层级创建
     */
    mkdirsForCustom(dirpath) {
        try {
            if (fs.existsSync(dirpath)) {
                return true;
            } else {
                if (this.mkdirsForCustom(path.dirname(dirpath))) {
                    fs.mkdirSync(dirpath);
                    return true;
                }
            }
        } catch (e) {
            console.error("create director fail! path=" + dirpath + " errorMsg:" + e);
            return false;
        }
    },

    /**
     * 微信加密字符串解密
     * @param {*} sessionKey 对话key
     * @param {*} iv 向量
     * @param {*} encryptedData 待解密字符串
     */
    wxBizDataCrypt(sessionKey, iv, encryptedData) {
        let WXBizDataCrypt = require('../libs/wxBizDataCrypt.js');
        let pc = new WXBizDataCrypt(this.app.config.weChat.appid, sessionKey);
        let data = pc.decryptData(encryptedData, iv);
        return JSON.parse(data);
    },

    /**
     * 时间戳格式化函数
     * @param {string} format  格式
     * @param  {int}    timestamp 要格式化的时间 默认为当前时间
     * @return {string}           格式化的时间字符串
     */
    changeDate(format, timestamp) {
        // formats格式包括
        // 1. Y-m-d
        // 2. Y-m-d H:i:s
        // 3. Y年m月d日
        // 4. Y年m月d日 H时i分
        format = format || 'Y-m-d';

        var zero = function (value) {
            if (value < 10) {
                return '0' + value;
            }
            return value;
        };

        var myDate = timestamp ? new Date(timestamp) : new Date();

        var year = myDate.getFullYear();
        var month = zero(myDate.getMonth() + 1);
        var day = zero(myDate.getDate());

        var hour = zero(myDate.getHours());
        var minite = zero(myDate.getMinutes());
        var second = zero(myDate.getSeconds());

        return format.replace(/Y|m|d|H|i|s/ig, function (matches) {
            return ({
                Y: year,
                m: month,
                d: day,
                H: hour,
                i: minite,
                s: second
            })[matches];
        });
    },

    /**
     * 获得时间差,时间格式为 年-月-日 小时:分钟:秒 或者 年/月/日 小时:分钟:秒 其中，年月日为全格式，例如 ： 2010-10-12 01:00:00
     * @param startTime 开始时间
     * @param endTime 结束时间
     * @param diffType 转换类型 0代表second 1代表minute 2代表hour 3代表day
     * @returns {number} 返回时间差
     */
    getDateDiff(startTime, endTime, diffType) {
        //将xxxx-xx-xx的时间格式，转换为 xxxx/xx/xx的格式
        startTime = startTime.replace(/-/g, "/");
        endTime = endTime.replace(/-/g, "/");
        let sTime = new Date(startTime); //开始时间
        let eTime = new Date(endTime); //结束时间
        //作为除数的数字
        let divNum = 1;
        switch (diffType) {
            case 0:
                divNum = 1000;
                break;
            case 1:
                divNum = 1000 * 60;
                break;
            case 2:
                divNum = 1000 * 3600;
                break;
            case 3:
                divNum = 1000 * 3600 * 24;
                break;
            default:
                break;
        }
        return parseInt((eTime.getTime() - sTime.getTime()) / parseInt(divNum));
    },

    /**
     * 封装 socket 请求数据格式
     * @param action 事件
     * @param payload 数据
     * @param metadata 元信息
     */
    parseMsg(action, payload = {}, metadata = {}) {
        // 封装 meta 数据,添加当前时间轴
        const meta = Object.assign({}, {
            timestamp: Date.now(),
        }, metadata);
        // 格式化返回数据
        return {
            meta,
            data: {
                action,
                payload,
            },
        };
    },
    /**
    * 封装 socket 请求数据格式
    * @param action 事件
    * @param payload 数据
    * @param metadata 元信息
    */
    parseMsgNoTime(action, payload = {}) {

        // 格式化返回数据
        return {
            data: {
                action,
                payload,
            },
        };
    }
}
